﻿// App.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include "pch.h"
#include <iostream>
#include <stdio.h>
#include <string>
#include <memory>
#include <dbghelp.h>
#include "grpc++/grpc++.h"
#include "gflags/gflags.h"
#include "EnclaveProvider.h"
#include "Service.h"

DEFINE_string(configFile, "./config/service.xml", "service config file");


void createDumpFile(LPCWSTR lpstrDumpFilePathName, EXCEPTION_POINTERS *pException)
{
	// 创建Dump文件
	//
	HANDLE hDumpFile = CreateFile(lpstrDumpFilePathName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

	// Dump信息
	//
	MINIDUMP_EXCEPTION_INFORMATION dumpInfo;
	dumpInfo.ExceptionPointers = pException;
	dumpInfo.ThreadId = GetCurrentThreadId();
	dumpInfo.ClientPointers = TRUE;

	// 写入Dump文件内容
	//
	MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hDumpFile, MiniDumpNormal, &dumpInfo, NULL, NULL);

	CloseHandle(hDumpFile);
}


LONG applicationCrashHandler(EXCEPTION_POINTERS *pException)
{
	createDumpFile(L"VaultService.dmp", pException);

	return EXCEPTION_EXECUTE_HANDLER;
}

int main(int argc, char **argv)
{
	SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)applicationCrashHandler);

	HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
	DWORD mode;
	GetConsoleMode(hStdin, &mode);
	mode &= ~ENABLE_QUICK_EDIT_MODE;  //移除快速编辑模式
	mode &= ~ENABLE_INSERT_MODE;      //移除插入模式
	mode &= ~ENABLE_MOUSE_INPUT;
	SetConsoleMode(hStdin, mode);

	google::InitGoogleLogging(argv[0]);

	google::ParseCommandLineFlags(&argc, &argv, true);

	google::SetLogDestination(ERROR, "log/server_");
	google::SetStderrLogging(google::GLOG_INFO);

	gflags::SetVersionString("0.0.0.1");
	gflags::SetUsageMessage("Vault service");

	LOG(INFO) << "Start valut Service ...";

    LOG(INFO) << "Create enclave";

    std::shared_ptr<EnclaveProvider> enclave_provider = std::shared_ptr<EnclaveProvider>(new EnclaveProvider());

	Service service(FLAGS_configFile, enclave_provider);

	if (enclave_provider->createEnclave(service.config_.id_) != 0)
	{
		return 0;
	}

    LOG(INFO) << "Create service";
    service.start();

	enclave_provider->destroyEnclave();

    google::ShutdownGoogleLogging();

	return 0;
}